package com.wan.net.rpc.service;

import com.wan.net.rpc.RpcManager;
import com.wan.net.rpc.util.RpcUtil;
import com.wan.util.cglib.FastClassUtil;
import net.sf.cglib.reflect.FastMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

/**
 * rpc服务提供者管理类
 * @author wwh
 * @date 2022/6/21 17:15
 */
public class ServiceProviderManager {
    private static final Logger logger = LoggerFactory.getLogger(ServiceProviderManager.class);
    private static final Map<String, ServiceProvider> PROVIDER_MAP = new HashMap<>();

    public static void addProvider(Object provider){
        Class<?> providerClass = provider.getClass();
        RService rService = providerClass.getAnnotation(RService.class);
        if(rService == null){
            return;
        }
        Class<?>[] interfaces = providerClass.getInterfaces();
        if(interfaces.length == 0){
            logger.error("rpc服务没有上级接口,provider:{},type:{}",provider,providerClass);
            return;
        }
        //默认取第一个接口，所以服务接口必须放在implements后首位
        Class<?> serviceInterface = interfaces[0];
        RpcService rpcService = RpcService.create()
                .serviceInterface(serviceInterface)
                .addParam(RpcService.VERSION,rService.version())
                .addParam(RpcService.DESC,rService.desc())
                .addParam(RpcService.IMPLEMENT,providerClass.getName());
        //接口的所有Public方法
        Method[] methods = serviceInterface.getMethods();
        for (Method method : methods) {
            int modifiers = method.getModifiers();
            if(Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers)){
                continue;
            }
            String serviceName = RpcUtil.buildServiceMethodName(serviceInterface,method.getName(),method.getParameterTypes(),providerClass.getName());
            FastMethod fastMethod = FastClassUtil.getFastMethod(method);
            PROVIDER_MAP.put(serviceName, new ServiceProvider(provider,fastMethod));
        }
        //注册绑定到服务中心
        RpcManager.registryService(rService.serverName(),rpcService);
    }

    public static ServiceProvider getProvider(String serviceName){
        return PROVIDER_MAP.get(serviceName);
    }

}
